import { createLocator } from "../../utils/locate.js";
import { uuid } from "../../utils/uuid.js";

function LetterComponent(props) {
  const { letter, row, col } = props;
  const div = document.createElement("div");
  div.className = "letter";
  div.innerHTML = letter;
  div.dataset.row = row;
  div.dataset.col = col;

  div.addEventListener("click", () => {
    div.classList.toggle("selected");
    document.dispatchEvent(new CustomEvent("letter-click", { detail: div }));
  });
  return div;
}

function LineComponent(props) {
  const { row, children, className } = props;
  const div = document.createElement("div");
  div.className = className ? className : "line";
  div.dataset.row = row;
  children.forEach((child) => div.appendChild(child));
  return div;
}

function BlockComponent(props) {
  const { children, rows, cols } = props;
  const div = document.createElement("div");
  div.className = "block";
  div.dataset.rows = rows;
  div.dataset.cols = cols;
  children.forEach((child) => div.appendChild(child));
  return div;
}

function createApp(props) {
  const { children } = props;
  let app = document.getElementById("app");
  if (!app) {
    app = document.createElement("div");
    app.id = "app";
    document.body.appendChild(app);
  }
  children.forEach((child) => app.appendChild(child));
}

function CodeComponent(props) {
  const component_id = uuid();
  const { source } = props;
  const lines = source.split("\n");
  const cols = Math.max(...lines.map((line) => line.length));

  const rowNumber = Array.from({ length: lines.length }, (_, row) =>
    LetterComponent({ letter: row, row, col: -1 })
  );
  const rowNumberDiv = document.createElement("div");
  rowNumberDiv.className = "row-number";
  rowNumber.forEach((child) => rowNumberDiv.appendChild(child));

  const codeDiv = document.createElement("div");
  codeDiv.className = "code";
  codeDiv.id = component_id;
  codeDiv.appendChild(rowNumberDiv);

  document.addEventListener("letter-click", (e) => {
    const { detail } = e;
    if (!codeDiv.contains(detail)) return;
    const row = detail.dataset.row;
    const col = detail.dataset.col;
    const colNumberDiv = codeDiv.querySelector(".col-number");
    rowNumberDiv
      .querySelector(`[data-row="${row}"]`)
      .classList.toggle("selected");
    colNumberDiv
      .querySelector(`[data-col="${col}"]`)
      .classList.toggle("selected");
  });

  const codeBlock = BlockComponent({
    rows: lines.length,
    cols: cols,
    children: [
      LineComponent({
        row: -1,
        className: "col-number",
        children: Array.from({ length: cols }, (_, col) =>
          LetterComponent({ letter: col, row: -1, col })
        ),
      }),
      ...lines.map((line, row) =>
        LineComponent({
          row: row,
          children: line
            .split("")
            .map((letter, col) => LetterComponent({ letter, row, col })),
        })
      ),
    ],
  });

  codeDiv.appendChild(codeBlock);

  return codeDiv;
}

const [src, tar, tarMap] = await Promise.all(
  (
    await Promise.all([
      fetch("../src.txt"),
      fetch("../tar.txt"),
      fetch("../tar.txt.map"),
    ])
  ).map((p, i) => (i === 2 ? p.json() : p.text()))
);

const srcLocate = createLocator(src);
const tarLocate = createLocator(tar);

console.log(tarMap);

createApp({
  children: [CodeComponent({ source: src }), CodeComponent({ source: tar })],
});
